﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web;
using WarOfDev.Core.ExceptionHandling.Exceptions;
using WarOfDev.Core.ExceptionHandling.ExceptionDetails;
using WarOfDev.Core.ExceptionHandling.ExceptionCodes;

namespace WarOfDev.Core.ExceptionHandling.Attributes
{
    public abstract class BaseHandleErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
            {
                return;
            }

            var exception = filterContext.Exception;

            // Only "Server Internal Error" should be handled
            if (new HttpException(null, exception).GetHttpCode() != 500)
            {
                return;
            }

            if (!this.ExceptionType.IsInstanceOfType(exception))
            {
                return;
            }

            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

            if (exception is WofException<FrontendDetail>)
            {
                var exceptionDetail = exception as WofException<FrontendDetail>;

                //var detail = ((dynamic)exception).Detail;

                if (exceptionDetail.Detail.ErrorCode == ErrorCodes.Frontend.WOD_UNAUTHORIZED_NO_RIGHTS.Code)
                {
                    this.HandleAuthorizationException(filterContext);
                }

                if (exceptionDetail.Detail.ErrorCode == ErrorCodes.Frontend.WOD_SESSION_TIMEOUT.Code)
                {
                    this.HandleSessionExpiredException(filterContext);
                }
            }
        }

        protected static string GetDisplayText(Exception exception)
        {
            if (exception is WofException<FrontendDetail>)
            {
                return ((dynamic)exception).Detail.ErrorMessage;
            }

            return "Unknown ErrorMessage";
        }

        /// <summary>
        /// Handles session timeout exceptions.
        /// </summary>
        /// <param name="context">The exception context information.</param>
        protected abstract void HandleSessionExpiredException(ExceptionContext context);

        /// <summary>
        /// Handles authorization exceptions.
        /// </summary>
        /// <param name="context">The exception context information.</param>
        protected abstract void HandleAuthorizationException(ExceptionContext context);

        /// <summary>
        /// Handles all frontend exceptions.
        /// </summary>
        /// <param name="context">The exception context information.</param>
        protected abstract void HandleFrontendException(ExceptionContext context);

    }
}
